/**
 * 
 */
package com.gr.staffpm.widget.date;

import java.util.Date;

import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.form.TextField;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.odlabs.wiquery.core.javascript.JsQuery;
import org.odlabs.wiquery.core.javascript.JsStatement;
import org.odlabs.wiquery.core.options.Options;
import org.odlabs.wiquery.ui.datepicker.DateOption;
import org.odlabs.wiquery.ui.datepicker.DatePicker.ShowOnEnum;
import org.odlabs.wiquery.ui.datepicker.DatePickerOptions;

import com.gr.staffpm.css.CssScope;
import com.gr.staffpm.js.StaffPMJSScope;
import com.gr.staffpm.model.DateModel;


/**
 * @author Graham Rhodes 7 Jul 2011 14:46:05
 */
public class DatePicker extends TextField<Date> implements IHeaderContributor {

    private static final long serialVersionUID = 1L;
    private final DatePickerOptions options;

    public DatePicker(String id) {
        super(id, new DateModel(new DateTime()));
        options = new DatePickerOptions(this);
        options.setShowOn(ShowOnEnum.FOCUS);
        options.setDateFormat("dd/mm/yy");
    }

    public DatePicker(String id, DateTime date) {
        super(id, new DateModel(date));
        options = new DatePickerOptions(this);
        options.setShowOn(ShowOnEnum.FOCUS);
        options.setDateFormat("dd/mm/yy");
    }

    @Override
    public void renderHead(IHeaderResponse response) {
        response.renderCSSReference(new ResourceReference(CssScope.class, "jquery-ui-1.8.14.custom.css"));
        response.renderJavascriptReference(new ResourceReference(StaffPMJSScope.class, "jquery-ui-1.8.14.custom.min.js"));
        response.renderOnDomReadyJavascript(statement().render().toString());
    }

    @Override
    protected void detachModel() {
        super.detachModel();
        options.detach();
    }

    public JsStatement statement() {
        return new JsQuery(this).$().chain("datepicker", options.getOptions().getJavaScriptOptions());
    }

    /**Method retrieving the options of the component
     * @return the options
     */
    protected Options getOptions() {
        return options.getOptions();
    }

    /*---- Methods section ---*/
    /**Method to destroy the datepicker
     * This will return the element back to its pre-init state.
     * @return the associated JsStatement
     */
    public JsStatement destroy() {
        return new JsQuery(this).$().chain("datepicker", "'destroy'");
    }

    /**Method to destroy the datepicker within the ajax request
     * @param ajaxRequestTarget
     */
    public void destroy(AjaxRequestTarget ajaxRequestTarget) {
        ajaxRequestTarget.appendJavascript(this.destroy().render().toString());
    }

    /**Method to disable the datepicker
     * @return the associated JsStatement
     */
    public JsStatement disable() {
        return new JsQuery(this).$().chain("datepicker", "'disable'");
    }

    /**Method to disable the datepicker within the ajax request
     * @param ajaxRequestTarget
     */
    public void disable(AjaxRequestTarget ajaxRequestTarget) {
        ajaxRequestTarget.appendJavascript(this.disable().render().toString());
    }

    /**Method to enable the datepicker
     * @return the associated JsStatement
     */
    public JsStatement enable() {
        return new JsQuery(this).$().chain("datepicker", "'enable'");
    }

    /**Method to enable the datepicker within the ajax request
     * @param ajaxRequestTarget
     */
    public void enable(AjaxRequestTarget ajaxRequestTarget) {
        ajaxRequestTarget.appendJavascript(this.enable().render().toString());
    }

    /**Method returning the current date for the datepicker
     * @return the date
     */
    public DateTime getDate() {
        if (getValue().matches("^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[012])/\\d\\d$"))
            return DateTimeFormat.forPattern("dd/MM/yy").parseDateTime(getValue());
        return DateTimeFormat.forPattern("dd/MM/yyyy").parseDateTime(getValue());
    }

    /**Method to hide the datepicker
     * @param speed The speed at which to close the date picker.
     * @return the associated JsStatement
     */
    public JsStatement hide(short speed) {
        return new JsQuery(this).$().chain("datepicker", "'hide'", Short.toString(speed));
    }

    /**Method to hide the datepicker within the ajax request
     * @param ajaxRequestTarget
     * @param speed The speed at which to close the date picker.
     */
    public void hide(AjaxRequestTarget ajaxRequestTarget, short speed) {
        ajaxRequestTarget.appendJavascript(this.hide(speed).render().toString());
    }

    /**Method to hide the datepicker
     * @return the associated JsStatement
     */
    public JsStatement hide() {
        return new JsQuery(this).$().chain("datepicker", "'hide'");
    }

    /**Method to hide the datepicker within the ajax request
     * @param ajaxRequestTarget
     */
    public void hide(AjaxRequestTarget ajaxRequestTarget) {
        ajaxRequestTarget.appendJavascript(this.hide().render().toString());
    }

    /**Method to set the date of the datepicker
     * @param dateOption Date to set
     * @return the associated JsStatement
     */
    public JsStatement setDate(DateTime dateParam) {
        return new JsQuery(this).$().chain("datepicker", "'setDate'", new DateOption(dateParam.toDate()).getJavascriptOption());
    }

    /**Method to set the date of the datepicker within the ajax request
     * @param ajaxRequestTarget
     * @param dateOption Date to set
     */
    public void setDate(AjaxRequestTarget ajaxRequestTarget, DateTime dateParam) {
        ajaxRequestTarget.appendJavascript(this.setDate(dateParam).render().toString());
    }

    /**Method to show the datepicker
     * @return the associated JsStatement
     */
    public JsStatement show() {
        return new JsQuery(this).$().chain("datepicker", "'show'");
    }

    /**Method to show the datepicker within the ajax request
     * @param ajaxRequestTarget
     */
    public void show(AjaxRequestTarget ajaxRequestTarget) {
        ajaxRequestTarget.appendJavascript(this.show().render().toString());
    }

    /**Method to returns the .ui-datepicker  element
     * @return the associated JsStatement
     */
    public JsStatement widget() {
        return new JsQuery(this).$().chain("datepicker", "'widget'");
    }

    /**Method to returns the .ui-datepicker element within the ajax request
     * @param ajaxRequestTarget
     */
    public void widget(AjaxRequestTarget ajaxRequestTarget) {
        ajaxRequestTarget.appendJavascript(this.widget().render().toString());
    }

}
